﻿using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

namespace Miao.UI
{
    [RequireComponent(typeof(RectTransform))]
    public class FlexibleWrapLayout : LayoutGroup
    {
        [SerializeField] private float m_SpacingX = 0f;
        [SerializeField] private float m_SpacingY = 0f;
        [SerializeField] private bool m_ChildForceExpandWidth = false;
        [SerializeField] private bool m_ChildForceExpandHeight = false;
        //[SerializeField] private TextAnchor m_ChildAlignment = TextAnchor.UpperLeft;

        public float spacingX
        {
            get { return m_SpacingX; }
            set { SetProperty(ref m_SpacingX, value); }
        }

        public float spacingY
        {
            get { return m_SpacingY; }
            set { SetProperty(ref m_SpacingY, value); }
        }

        public bool childForceExpandWidth
        {
            get { return m_ChildForceExpandWidth; }
            set { SetProperty(ref m_ChildForceExpandWidth, value); }
        }

        public bool childForceExpandHeight
        {
            get { return m_ChildForceExpandHeight; }
            set { SetProperty(ref m_ChildForceExpandHeight, value); }
        }

        //public TextAnchor childAlignment
        //{
        //    get { return m_ChildAlignment; }
        //    set { SetProperty(ref m_ChildAlignment, value); }
        //}

        // 存储每行的信息
        private struct RowInfo
        {
            public List<RectTransform> children;
            public float width;
            public float height;
            public float yPos;

            public RowInfo(float yPos)
            {
                this.children = new List<RectTransform>();
                this.width = 0f;
                this.height = 0f;
                this.yPos = yPos;
            }
        }

        public override void CalculateLayoutInputHorizontal()
        {
            base.CalculateLayoutInputHorizontal();

            // 计算最小和首选宽度
            var totalMin = 0f;
            var totalPreferred = 0f;

            for (int i = 0; i < rectChildren.Count; i++)
            {
                var child = rectChildren[i];
                var childMinWidth = LayoutUtility.GetMinWidth(child);
                var childPreferredWidth = LayoutUtility.GetPreferredWidth(child);

                totalMin = Mathf.Max(totalMin, childMinWidth);
                totalPreferred = Mathf.Max(totalPreferred, childPreferredWidth);
            }

            SetLayoutInputForAxis(totalMin, totalPreferred, -1, 0);
        }

        public override void CalculateLayoutInputVertical()
        {
            var minHeight = 0f;
            var preferredHeight = 0f;

            if (rectChildren.Count > 0)
            {
                var rows = CalculateRows();
                var totalHeight = 0f;

                for (int i = 0; i < rows.Count; i++)
                {
                    totalHeight += rows[i].height;
                    if (i > 0)
                        totalHeight += spacingY;
                }

                minHeight = preferredHeight = totalHeight;
            }

            SetLayoutInputForAxis(minHeight, preferredHeight, -1, 1);
        }

        public override void SetLayoutHorizontal()
        {
            SetLayout();
        }

        public override void SetLayoutVertical()
        {
            SetLayout();
        }

        private void SetLayout()
        {
            var rows = CalculateRows();

            // 设置每个子元素的位置
            for (int rowIndex = 0; rowIndex < rows.Count; rowIndex++)
            {
                var row = rows[rowIndex];
                ArrangeRow(row);
            }
        }

        private List<RowInfo> CalculateRows()
        {
            var rows = new List<RowInfo>();
            var availableWidth = rectTransform.rect.width - padding.horizontal;

            if (rectChildren.Count == 0)
                return rows;

            var currentRow = new RowInfo(0f);
            rows.Add(currentRow);

            for (int i = 0; i < rectChildren.Count; i++)
            {
                var child = rectChildren[i];
                var childWidth = LayoutUtility.GetPreferredWidth(child);
                var childHeight = LayoutUtility.GetPreferredHeight(child);

                // 检查当前行是否能容纳这个子元素
                var neededWidth = childWidth;
                if (currentRow.children.Count > 0)
                    neededWidth += spacingX;

                // 如果当前行放不下且不是行的第一个元素，则换行
                if (currentRow.children.Count > 0 && currentRow.width + neededWidth > availableWidth)
                {
                    // 创建新行
                    var yPos = currentRow.yPos - currentRow.height - spacingY;
                    currentRow = new RowInfo(yPos);
                    rows.Add(currentRow);
                    neededWidth = childWidth; // 新行不需要间距
                }

                // 将子元素添加到当前行
                currentRow.children.Add(child);
                currentRow.width += neededWidth;
                currentRow.height = Mathf.Max(currentRow.height, childHeight);

                // 更新rows列表中的引用
                rows[rows.Count - 1] = currentRow;
            }

            return rows;
        }

        private void ArrangeRow(RowInfo row)
        {
            var availableWidth = rectTransform.rect.width - padding.horizontal;
            float currentX = padding.left;

            // 根据对齐方式调整起始X位置
            if (childAlignment == TextAnchor.UpperCenter || childAlignment == TextAnchor.MiddleCenter || childAlignment == TextAnchor.LowerCenter)
            {
                currentX += (availableWidth - row.width) * 0.5f;
            }
            else if (childAlignment == TextAnchor.UpperRight || childAlignment == TextAnchor.MiddleRight || childAlignment == TextAnchor.LowerRight)
            {
                currentX += availableWidth - row.width;
            }

            for (int i = 0; i < row.children.Count; i++)
            {
                var child = row.children[i];
                var childWidth = LayoutUtility.GetPreferredWidth(child);
                var childHeight = LayoutUtility.GetPreferredHeight(child);

                if (i > 0)
                    currentX += spacingX;

                // 计算Y位置（基于行的Y位置和子元素在行内的对齐）
                var yPos = row.yPos;
                if (childAlignment == TextAnchor.MiddleLeft || childAlignment == TextAnchor.MiddleCenter || childAlignment == TextAnchor.MiddleRight)
                {
                    yPos -= (row.height - childHeight) * 0.5f;
                }
                else if (childAlignment == TextAnchor.LowerLeft || childAlignment == TextAnchor.LowerCenter || childAlignment == TextAnchor.LowerRight)
                {
                    yPos -= (row.height - childHeight);
                }

                // 设置子元素位置和大小
                SetChildAlongAxis(child, 0, currentX, childForceExpandWidth ? availableWidth / row.children.Count - spacingX : childWidth);
                SetChildAlongAxis(child, 1, yPos, childForceExpandHeight ? row.height : childHeight);

                currentX += childWidth;
            }
        }

#if UNITY_EDITOR
        protected override void OnValidate()
        {
            base.OnValidate();
            // 在编辑器中实时更新布局
            SetDirty();
        }
#endif
    }
}